package com.atung.parking.config.tlPay;

import allinpay.syb.lib.HttpConnectionUtil;
import allinpay.syb.lib.SybConstants;
import allinpay.syb.lib.SybUtil;
import com.alibaba.fastjson.JSON;
import com.atung.parking.AiRencheParking;
import com.atung.parking.entity.BusParkingIot;
import com.atung.parking.entity.BusParkingOrders;
import com.atung.parking.enums.OrderState;
import com.atung.parking.enums.OrderType;
import com.atung.parking.mapper.BusParkingIotMapper;
import com.atung.parking.mapper.BusParkingOrdersMapper;
import com.atung.parking.request.AiRencheParkingRequest;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Component
@Log4j2
public class PayService {
    @Resource
    private BusParkingOrdersMapper busParkingOrdersMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private BusParkingIotMapper busParkingIotMapper;

    /**
     * cusid：商户号
     * appid：应用ID
     * version：版本号（默认为12）
     * trxamt：付款金额（单位为分）
     * notify_url：服务器异步通知页面路径
     * body：订单标题
     * paytype：支付方式（小程序固定W06）
     * randomstr	随机字符串
     * signtype	签名类型
     * sign	签名
     *
     * @return
     * @throws Exception
     */
    public Object pay(String openId, String orderId, BigDecimal amount) throws Exception {

        String trxamt = amount.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString();
        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_PAY_API_URL);
        http.init();
        TreeMap<String, String> params = new TreeMap<String, String>();
        params.put("cusid", SybConstants.SYB_CUSID);
        params.put("appid", SybConstants.SYB_APPID);
        params.put("version", SybConstants.SYB_VERSION);
        params.put("trxamt", trxamt);
        params.put("notify_url", SybConstants.SYB_NOTIFY_URL);
        params.put("body", "泊豆泊车");
        params.put("paytype", SybConstants.SYB_TYPE);
        params.put("reqsn", orderId);
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("signtype", "RSA");
        params.put("acct", openId);
        params.put("validtime", "3");
        params.put("sign", SybUtil.unionSign(params));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys, "UTF-8");
        PaymentResponse paymentResponse = JSON.parseObject(result, PaymentResponse.class);
        if ("SUCCESS".equals(paymentResponse.getRetcode())) {
            return paymentResponse.getPayinfo();
        }
        throw new RuntimeException("拉取微信支付失败:" + paymentResponse.getReqsn());
    }

    /**
     * 收银台
     *
     * @param openId
     * @param orderId
     * @param amount
     * @return
     * @throws Exception
     */
    public Object counterPay(String openId, String orderId, BigDecimal amount) throws Exception {
        String trxamt = amount.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toString();
        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_PAY_API_URL);
        http.init();
        TreeMap<String, String> params = new TreeMap<String, String>();
        params.put("cusid", SybConstants.SYB_CUSID);
        params.put("appid", SybConstants.SYB_APPID);
        params.put("orgid", "56445106513A6W1");
        params.put("version", SybConstants.SYB_VERSION);
        params.put("trxamt", URLEncoder.encode(trxamt, "UTF-8"));
        params.put("reqsn", orderId);
        params.put("notify_url", SybConstants.SYB_NOTIFY_URL);
        params.put("body", "泊豆泊车");
        params.put("remark", "收银台统一支付");
        params.put("validtime", "3");
        params.put("limit_pay", "no_credit");
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("paytype", SybConstants.SYB_TYPE);
        params.put("signtype", "RSA");
        params.put("sign", SybUtil.unionSign(params));
        return params;
    }

    public void handleCallbackService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        TreeMap<String, String> params = getParams(request);
        log.info("=====获取当前参数==={}", params.toString());
        boolean isSign = SybUtil.validSign(params, SybConstants.SYB_RSA_PUB_KEY);// 接受到推送通知,首先验签

        log.info("=====验证状态{}", isSign);
        if (isSign) {
            //获取订单编号
            String orderId = params.get("cusorderid");
            log.info("=====订单编号{}", orderId);
            //修改订单时间
            BusParkingOrders busParkingOrders = busParkingOrdersMapper.selectById(orderId);
            log.info("=====订单信息{}", busParkingOrders);

            //获取车场信息
            BusParkingIot busParkingIot = busParkingIotMapper.selectById(busParkingOrders.getParkingIotId());
            if (Objects.isNull(busParkingIot)) {

                return;
            }

            if (Objects.isNull(busParkingOrders) ||
                    !OrderState.PENDING_PAYMENT.getCode().equals(busParkingOrders.getOrderStatus())) {
                log.info("====未知--", busParkingOrders);
                return;
            }
            //设置支付信息
            busParkingOrders.setOrderPaymentTime(String.valueOf(System.currentTimeMillis()));
            busParkingOrders.setOrderStatus(OrderState.PAID.getCode());
            //获取当前订单类型
//            .//车位
            if (OrderType.PARKING_ORDER.name().equals(busParkingOrders.getOrderType())) {

                String estParkStartTime = busParkingOrders.getEstParkStartTime();
                String estParkEndTime = busParkingOrders.getEstParkEndTime();
                stringRedisTemplate.opsForHash().put(busParkingOrders.getParkingIotId().toString(),
                        busParkingOrders.getLicensePlateNumber(), estParkStartTime + "-" + estParkEndTime);
                busParkingOrdersMapper.updateStatusById(busParkingOrders.getId(), busParkingOrders.getOrderPaymentTime(), busParkingOrders.getOrderStatus());

                List<String> rid = new ArrayList<>();
                if (StringUtils.hasText(busParkingIot.getRid())) {
                    rid = new ArrayList<>(Arrays.asList(busParkingIot.getRid().split(",")));
                }
                AiRencheParkingRequest build = AiRencheParkingRequest.builder()
                        .carno(busParkingOrders.getLicensePlateNumber())
                        .starttime(Long.parseLong(estParkStartTime) / 1_000)
                        .endtime(Long.parseLong(estParkEndTime) / 1_000)
                        .sid(busParkingIot.getSid())
                        .rid(rid)
                        .secretKey(busParkingIot.getSecretKey())
                        .build();
                log.info("===车辆实体类对象{}", build);
                //新增车辆信息todo
                AiRencheParking.saveCar(build);

            } else {
                String YYYY_MM_DD = busParkingOrders.getPackageUseDate();
                String[] HH_MM_SS = busParkingOrders.getPackageValidPeriod().split("-");
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
                try {
                    Date date = dateFormat.parse(YYYY_MM_DD);
                    Date startTime = timeFormat.parse(HH_MM_SS[0]);
                    Date endTime = timeFormat.parse(HH_MM_SS[1]);
                    // 设置日期和时间
                    startTime.setYear(date.getYear());
                    startTime.setMonth(date.getMonth());
                    startTime.setDate(date.getDate());
                    endTime.setYear(date.getYear());
                    endTime.setMonth(date.getMonth());
                    endTime.setDate(date.getDate());
                    stringRedisTemplate.opsForHash().put(busParkingOrders.getParkingIotId().toString(),
                            busParkingOrders.getLicensePlateNumber(), startTime.getTime() + "-" + endTime.getTime());
                    busParkingOrdersMapper.updateStatusById(busParkingOrders.getId(), busParkingOrders.getOrderPaymentTime(), busParkingOrders.getOrderStatus());
                    List<String> rid = new ArrayList<>();
                    if (StringUtils.hasText(busParkingIot.getRid())) {
                        rid = new ArrayList<>(Arrays.asList(busParkingIot.getRid().split(",")));
                    }
                    //新增车辆信息todo
                    AiRencheParkingRequest build = AiRencheParkingRequest.builder()
                            .carno(busParkingOrders.getLicensePlateNumber())
                            .starttime(startTime.getTime() / 1_000)
                            .endtime(endTime.getTime() / 1_000)
                            .sid(busParkingIot.getSid())
                            .rid(rid)
                            .secretKey(busParkingIot.getSecretKey())
                            .build();
                    log.info("===车辆实体类对象{}", build);
                    AiRencheParking.saveCar(build);
                } catch (ParseException e) {
                    e.printStackTrace();
                    log.error("========出现异常{}", e.getMessage());
                }

            }
        }

    }

    private TreeMap<String, String> getParams(HttpServletRequest request) {
        TreeMap<String, String> map = new TreeMap<String, String>();
        Map reqMap = request.getParameterMap();
        for (Object key : reqMap.keySet()) {
            String value = ((String[]) reqMap.get(key))[0];
            map.put(key.toString(), value);
        }
        return map;
    }

}
